package com.dou.sample.opengl_project.gl2;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import com.dou.sample.opengl_project.R;
import com.dou.sample.opengl_project.utls.MatrixHelper;
import com.dou.sample.opengl_project.utls.ShaderHelper;
import com.dou.sample.opengl_project.utls.TextResourceReader;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_LINES;
import static android.opengl.GLES20.GL_POINTS;
import static android.opengl.GLES20.GL_TRIANGLE_FAN;
import static android.opengl.GLES20.glDrawArrays;
import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glGetAttribLocation;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glUniformMatrix4fv;
import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glVertexAttribPointer;

/**
 * Created by Dou on 2018/1/15.
 */

public class AirHockeyRenderer2 implements GLSurfaceView.Renderer {

    Context context;

    private static final int POSITION_COMPONENT_COUNT = 2;
    private static final int COLOR_COMPONENT_COUNT = 3;

    private static final int BYTES_PER_FLOAT = 4;

    private static final int STRIDE = (POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT;

    private FloatBuffer vertexBuffer;

    private FloatBuffer boarderBuffer;

    int program;

    private static final String A_COLOR = "a_Color";
    int aColorLocation;

    private static final String A_POSITION = "a_Position";
    int aPositionLocation;

    private static final String U_MATRIX = "u_Matrix";
    int uMatrixLocation;

    final float[] projectMatrix = new float[16];

    final float[] modelMatrix = new float[16];

    // vertexs
    float[] tableVertexs = {
            0,0,
            -0.5f, -0.5f,
            0.5f, -0.5f,
            0.5f, 0.5f,
            -0.5f,0.5f
    };

    // triangles
    float[] indices = {
//            // triangle one
//            -0.5f,-0.5f,
//            0.5f,0.5f,
//            -0.5f,.5f,
//
//            // triangle two
//            -.5f,-.5f,
//            .5f,-.5f,
//            .5f,.5f,

            0,0,1,1,1,
            -0.5f, -0.8f,.7f,.7f,.7f,
            0.5f, -0.8f,.7f,.7f,.7f,
            0.5f, 0.8f,.7f,.7f,.7f,
            -0.5f,0.8f,.7f,.7f,.7f,
            -0.5f, -0.8f,.7f,.7f,.7f,

            // line
            -.5f,0,1,0,0,
            .5f,0,1,0,0,

            // mallets
            0,-0.5f,0,0,1,
            0,0.5f,1,0,0
    };

    float[] boarder = {
            // triangle one
            -0.45f,-0.45f,
            0.45f,0.45f,
            -0.45f,.45f,

            // triangle two
            -.45f,-.45f,
            .45f,-.45f,
            .45f,.45f,
    };

    public AirHockeyRenderer2(Context context){

        this.context = context;

        ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(BYTES_PER_FLOAT * indices.length);
        vertexByteBuffer.order(ByteOrder.nativeOrder());
        vertexBuffer = vertexByteBuffer.asFloatBuffer();
        vertexBuffer.put(indices);
        vertexBuffer.position(0);

//        boarderBuffer = ByteBuffer.allocateDirect(BYTES_PER_FLOAT * boarder.length).order(ByteOrder.nativeOrder()).asFloatBuffer();
//        boarderBuffer.put(boarder);
//        boarderBuffer.position(0);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0,0,0,0);

        String vertexShaderString = TextResourceReader.readTextFileFromResource(context, R.raw.simple_vertex_shader);
        String fragmentShaderString = TextResourceReader.readTextFileFromResource(context, R.raw.simple_fragment_shader);

        int vertexShader = ShaderHelper.compileVertexShader(vertexShaderString);
        int fragmentShader = ShaderHelper.compileFragmentShader(fragmentShaderString);

        program = ShaderHelper.linkProgram(vertexShader, fragmentShader);
        glUseProgram(program);

        aPositionLocation = glGetAttribLocation(program, A_POSITION);
        aColorLocation = glGetAttribLocation(program, A_COLOR);
        uMatrixLocation = glGetUniformLocation(program, U_MATRIX);

        vertexBuffer.position(0);
        glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, STRIDE, vertexBuffer);
        glEnableVertexAttribArray(aPositionLocation);

        vertexBuffer.position(POSITION_COMPONENT_COUNT);
        glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT, false, STRIDE, vertexBuffer);
        glEnableVertexAttribArray(aColorLocation);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0,0,width,height);
        MatrixHelper.perspectiveM(projectMatrix, 60, (float) width / (float) height, 1f, 10f);

        Matrix.setIdentityM(modelMatrix, 0);
        Matrix.translateM(modelMatrix, 0, 0, 0, -2.5f);
        Matrix.rotateM(modelMatrix, 0, -60, 1, 0, 0);

        float[] temp = new float[16];
        Matrix.multiplyMM(temp, 0, projectMatrix, 0, modelMatrix, 0);
        System.arraycopy(temp, 0, projectMatrix, 0, temp.length);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        glUniformMatrix4fv(uMatrixLocation, 1, false, projectMatrix, 0);

        glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

        glDrawArrays(GL_LINES, 6, 2);

        glDrawArrays(GL_POINTS, 8, 1);

        glDrawArrays(GL_POINTS, 9, 1);
    }
}
